from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from server.models import WaitedReviewPicture, Message, Picture, Tag, PictureTag, Abracadabra, UsePictureLog, \
    UseOrderLog, UseSearchTagLog
from server.config import FTP_SERVER_AZURE, FTP_SERVER_COMPRESS_AZURE
from server.utils import get_ip, write_file, FtpHandler, fix_server, add_server_address
import random
import openai
from server.secrets import OpenAI_API_Key
import json

ftpHandler = FtpHandler()


# Create your views here.
def write_search_tag_log(request, tag):
    search_tag_log = UseSearchTagLog()
    search_tag_log.description = 'search'
    search_tag_log.ip = get_ip(request)
    search_tag_log.tag = tag
    search_tag_log.save()


def write_order_log(request, description, order_mode):
    order_log = UseOrderLog()
    order_log.ip = get_ip(request)
    order_log.description = description
    order_log.order_mode = order_mode
    order_log.save()


def home(request):
    return HttpResponse('home')


@csrf_exempt
def add_pic(request):
    picname = request.POST.get('fileName')
    prefix = request.POST.get('prefix')
    tags = request.POST.get('tags')
    create_time = request.POST.get('ctime')
    negative_tags = request.POST.get('negative_tags')
    pics = Picture.objects.filter(image_name=picname)
    if len(pics) == 0:
        print('添加文件 {}。'.format(picname))
        picture = Picture()
        picture.image_name = picname
        picture.prefix = prefix
        picture.tags = tags
        picture.negative_tags = negative_tags
        picture.create_time = create_time
        # datetime.datetime.today().timestamp()
        picture.save()
    else:
        print('修改文件 {}。'.format(picname))
        picture = pics[0]
        picture.prefix = prefix
        picture.tags = tags
        picture.negative_tags = negative_tags
        picture.create_time = create_time
        picture.save()
    return HttpResponse(f'success {picname}')


# 用不上
def get_pic_list(request):
    pictures = Picture.objects.filter(is_show=1)
    picture_urls = []
    for idx, picture in enumerate(pictures):
        picture_urls.append(fix_server(idx, picture))
    return JsonResponse({
        "picture_urls": picture_urls
    })


def get_pic_info_list(request):
    pictures = Picture.objects.filter(is_show=1)
    picture_infos = []
    for idx, picture in enumerate(pictures):
        picture_infos.append(fix_server(idx, picture))
    write_order_log(request, 'login', 'id')
    return JsonResponse({
        "picture_infos": picture_infos
    })


def deactivate_from_id(request):
    picture_id = request.GET.get('id')
    pics = Picture.objects.filter(id=picture_id)
    for pic in pics:
        pic.is_show = False
        pic.save()
    return HttpResponse("successful deactivate image id:{}".format(picture_id))


def get_praise_number_id(request):
    picture_id = request.GET.get('id')
    pics = Picture.objects.filter(id=picture_id)
    if len(pics) > 0:
        return HttpResponse(pics[0].praise)
    else:
        return HttpResponse(0)


def praise_by_id(request):
    picture_id = request.GET.get('id')
    pics = Picture.objects.filter(id=picture_id)
    if len(pics) > 0:
        pic = pics[0]
        pic.praise = pic.praise + 1
        pic.save()
        pic_log = UsePictureLog()
        pic_log.target_id = pic
        pic_log.ip = get_ip(request)
        pic_log.description = 'praise'
        pic_log.save()
        return HttpResponse(pic.praise)
    else:
        return HttpResponse(0)


def get_pic_list_order(request):
    condition = request.GET.get('condition')
    reverse = request.GET.get('rev')
    if int(reverse) >= 0:
        pictures = Picture.objects.filter(is_show=1).order_by(condition)
        picture_infos = []
        for idx, picture in enumerate(pictures):
            picture_infos.append(fix_server(idx, picture))
        write_order_log(request, 'order {}'.format(condition), '{}'.format(condition))
        return JsonResponse({
            "picture_infos": picture_infos
        })
    else:
        pictures = Picture.objects.filter(is_show=1).order_by("-{}".format(condition))
        picture_infos = []
        for idx, picture in enumerate(pictures):
            picture_infos.append(fix_server(idx, picture))
        write_order_log(request, 'order {}'.format(condition), '-{}'.format(condition))
        return JsonResponse({
            "picture_infos": picture_infos
        })


def get_r12_pic_info_list(request):
    pictures = Picture.objects.filter(is_r18=0).order_by('-id')
    # print(pictures)
    picture_infos = []
    for idx, picture in enumerate(pictures):
        picture_infos.append(fix_server(idx, picture))
    write_order_log(request, 'login', 'not_r18')
    return JsonResponse({
        "picture_infos": picture_infos
    })


def update_pic_to_r12(request):
    picture_id = request.GET.get('id')
    pics = Picture.objects.filter(id=picture_id)
    for pic in pics:
        pic.is_r18 = False
        pic.save()
    return HttpResponse("successful update image id:{}".format(picture_id))


def get_no_visual_pic_info_list(request):
    pictures = Picture.objects.filter(is_show=0)
    picture_infos = []
    for idx, picture in enumerate(pictures):
        picture_infos.append(fix_server(idx, picture))
    write_order_log(request, 'login', 'no_visual')
    return JsonResponse({
        "picture_infos": picture_infos
    })


def get_chosen_pic_info_list(request):
    pictures = Picture.objects.filter(is_show=True).filter(is_chosen=True).order_by("-id")
    picture_infos = []
    for idx, picture in enumerate(pictures):
        picture_infos.append(fix_server(idx, picture))
    write_order_log(request, 'login', 'chosen')
    return JsonResponse({
        "picture_infos": picture_infos
    })


def choose_pic_by_id(request):
    picture_id = request.GET.get('id')
    pics = Picture.objects.filter(id=picture_id)
    for pic in pics:
        pic.is_chosen = True
        pic.save()
    return HttpResponse("Successfully choose image id:{}".format(picture_id))


def cancel_choose_pic_by_id(request):
    picture_id = request.GET.get('id')
    pics = Picture.objects.filter(id=picture_id)
    pics[0].is_chosen = False
    pics[0].save()
    return HttpResponse("Successfully cancel choose image id:{}".format(picture_id))


def get_true_path_by_id(request):
    pic_id = request.GET.get('id')
    pics = Picture.objects.filter(id=pic_id)
    if len(pics) > 0:
        return HttpResponse("{}{}".format(FTP_SERVER_AZURE, pics[0].image_name))
    else:
        return HttpResponse('none')


def get_number_pic(request):
    pics = Picture.objects.all()
    total_pics = len(pics)
    pics_show = pics.filter(is_show=True)
    total_showed_pics = len(pics_show)
    pics_chosen = pics.filter(is_chosen=True)
    total_chosen_pics = len(pics_chosen)
    return JsonResponse({
        'total_pics': total_pics,
        'total_showed_pics': total_showed_pics,
        'total_chosen_pics': total_chosen_pics
    })


def get_pali_paths(request):
    pics_show = Picture.objects.filter(is_show=True)
    total_showed_pics = len(pics_show)

    page_number = int(request.GET.get('page', default='1'))
    number_per_page = int(request.GET.get('per', default='12'))
    if page_number < total_showed_pics / number_per_page:
        picture_infos = []
        for i in range((page_number - 1) * number_per_page, page_number * number_per_page):
            picture = pics_show[i]
            picture_infos.append(fix_server(i, picture))
        return JsonResponse({
            "picture_infos": picture_infos
        })
    else:
        picture_infos = []
        for i in range(total_showed_pics - number_per_page, total_showed_pics):
            picture = pics_show[i]
            picture_infos.append(fix_server(i, picture))
        return JsonResponse({
            "picture_infos": picture_infos
        })


@csrf_exempt
def upload_pic(request):
    if request.method == "POST":
        file_data = request.FILES.getlist('file')
        for file in file_data:
            try:
                ftpHandler.add_image(file)
            except Exception as e:
                return JsonResponse({'msg': '上传失败：' + str(e), 'type': 'error'})
        return JsonResponse({'msg': '上传成功！', 'type': 'success'})


def carousel(request):
    number = int(request.GET.get('number', default=6))
    pics = Picture.objects.filter(is_chosen=True)
    picture_infos = []
    for i in range(number):
        picture = pics[i]
        picture_infos.append(fix_server(i, picture))
    return JsonResponse({
        "picture_infos": picture_infos
    })


def water_pics(request):
    showed_pictures = request.GET.get('showPictures', '[0]')
    print(showed_pictures)
    showed_pictures = list(showed_pictures.strip('[').strip(']').split(','))
    showed_pictures = [int(i) for i in showed_pictures]
    pictures_number = int(request.GET.get('num', 30))
    pictures = Picture.objects.filter(is_show=1).exclude(id__in=showed_pictures)
    picture_infos = []
    if len(list(pictures)) < pictures_number:
        pictures_number = len(list(pictures))
    sample_pic_list = random.sample(list(pictures), pictures_number)
    for idx, picture in enumerate(sample_pic_list):
        picture_infos.append(fix_server(idx, picture))
    write_order_log(request, 'waterfall', 'id')
    return JsonResponse({
        "picture_infos": picture_infos,
        "code": 200  # 请求成功
    })


def pic_resurgence(request):
    pic_id = request.GET.get('id')
    pics = Picture.objects.filter(id=pic_id)
    if len(pics) != 0:
        pic = pics[0]
        pic.is_show = True
    else:
        pass
    return HttpResponse("resurgence successful")


def get_abracadabra_list(request):
    query = Abracadabra.objects.all()
    res = []
    for item in query:
        # print(item)
        res.append({'id': item.id, 'name': item.name, 'tag': item.tag, 'negative_tag': item.negative_tag,
                    'sample_image_url': item.sample_image_url})
    return JsonResponse({
        "abracadabra_infos": res
    })


def invisible_water_pics(request):
    showed_pictures = request.GET.get('showPictures', '[0]')
    showed_pictures = list(showed_pictures.strip('[').strip(']').split(','))
    showed_pictures = [int(i) for i in showed_pictures]
    pictures_number = int(request.GET.get('num', 100))
    pictures = Picture.objects.filter(is_show=0).exclude(id__in=showed_pictures)
    picture_infos = []
    if len(list(pictures)) < pictures_number:
        pictures_number = len(list(pictures))
    sample_pic_list = random.sample(list(pictures), pictures_number)
    for idx, picture in enumerate(sample_pic_list):
        picture_infos.append(fix_server(idx, picture))
    write_order_log(request, 'waterfall', 'id')
    return JsonResponse({
        "picture_infos": picture_infos,
        "code": 200  # 请求成功
    })


###################
# 搜索页面后端请求函数
###################
def get_random_tag(request):
    num = int(request.GET.get('num', default=5))
    tags = list(Tag.objects.filter(count__gt=30).order_by('?')[:num].values('tag_name'))
    return JsonResponse({
        'tags': tags
    })


def get_hot_tag(request):
    num = int(request.GET.get('num', 10))
    hot_tag = Tag.objects.filter(is_general=0).order_by('-count').values('tag_name', 'count')[:num]
    # print(list(hot_tag))
    return JsonResponse({
        "hot_tag": list(hot_tag),
    })


def search_tag_candidate(request):
    num = int(request.GET.get('num', 5))
    tag = request.GET.get('keyword').strip().lower()
    res = Tag.objects.filter(tag_name__contains=tag).values('tag_name', 'count')
    if num != -1:
        res = res[:num]
    return JsonResponse({
        "tag_candidate": list(res),
    })


def search_tag(request):
    # 输入单个tag，查询含有该tag的图片
    tag = request.GET.get('keyword').strip().lower()
    # 查询Tag表，找到对应的tag_id
    tag_id = Tag.objects.filter(tag_name=tag)
    if len(tag_id) == 0:
        return JsonResponse({
            "keyword": tag,
            "picture_infos": [],
        })
    # 查询PictureTag表，找到对应的pics_id
    pics_id = list(PictureTag.objects.filter(tag_id=tag_id[0].id).values_list('picture_id', flat=True))
    # 查询Picture表，找到对应的image_name
    picture_infos = list(
        Picture.objects.filter(is_show=1).filter(id__in=pics_id).order_by('-id').values('id', 'image_name', 'praise'))
    for idx, item in enumerate(picture_infos):
        item['url'] = add_server_address(idx, item['image_name'])
    # picture_infos = []
    # for idx, pic in enumerate(res):
    #     picture_infos.append(fix_server(idx, pic))
    # 查询Picture表，找到对应的image_name
    write_search_tag_log(request, tag)
    return JsonResponse({
        "keyword": tag,
        "picture_infos": picture_infos,
    })


def search_multi_tag(request):
    # ===未经过测试！！禁止使用！！===
    # 输入多个tag，查询同时含有这些tag的图片
    tags = request.GET.get('keyword').strip().lower().split()
    # 查询Tag表，找到对应的tag_id
    tag_ids = []
    for tag in tags:
        tag_id = Tag.objects.filter(tag_name=tag)
        if len(tag_id) == 0:
            return JsonResponse({
                "keyword": tag,
                "picture_infos": [],
            })
        tag_ids.append(tag_id[0].id)
    # 查询PictureTag表，找到对应的pics_id
    pics_id = list(PictureTag.objects.filter(tag_id__in=tag_ids).values_list('picture_id', flat=True))
    # 查询Picture表，找到对应的image_name
    res = Picture.objects.filter(id__in=pics_id)
    picture_infos = []
    for idx, pic in enumerate(res):
        picture_infos.append(fix_server(idx, pic))
    write_search_tag_log(request, tags)
    return JsonResponse({
        "keyword": tags,
        "picture_infos": picture_infos,
    })


@csrf_exempt
def upload_from_server(request):
    file = request.FILES.getlist('file')[0]
    try:
        ftpHandler.add_image(file)
    except Exception as e:
        return JsonResponse({'msg': '上传失败: ' + str(e), 'type': 'error'})
    return JsonResponse({'msg': '上传成功', 'type': 'success'})


def get_message(request):
    message = Message.objects.all().order_by('-id').values_list('content', flat=True)
    return JsonResponse({
        "message": list(message),
    })


def send_message(request):
    message = str(request.GET.get('message'))
    Message.objects.create(content=message, ip=get_ip(request))
    return JsonResponse({
        "res": "success",
    })


def get_waited_review_pics_info(request):
    pics = list(WaitedReviewPicture.objects.filter(is_delete=0, is_review=0).order_by('-id').values('id', 'image_name'))
    for idx, pic in enumerate(pics):
        pic['url'] = add_server_address(idx, pic['image_name'], is_waited_review=True)
    return JsonResponse({
        "pics": pics
    })


def pass_pic_by_id(request):
    pic_id = int(request.GET.get('id'))
    # image_name = str(request.GET.get('image_name'))
    pic = WaitedReviewPicture.objects.get(id=pic_id)
    if pic.is_review == 1 or pic.is_delete == 1:
        return JsonResponse({
            "res": "error",
        })
    else:
        pic.is_review = 1
        pic.save()
        ftpHandler.rename_pic(pic)
        return JsonResponse({
            "res": "success",
        })


def delete_pic_by_id(request):
    pic_id = int(request.GET.get('id'))
    pic = WaitedReviewPicture.objects.get(id=pic_id)
    pic.is_delete = 1
    pic.save()
    return JsonResponse({
        "res": "success",
    })


@csrf_exempt
def chat_gpt_v1(request):
    openai.api_key = OpenAI_API_Key
    post_data = json.loads(request.body.decode(encoding='utf-8'))
    prompt = post_data['prompt']
    try:
        response = openai.Completion.create(
            model="text-davinci-003",
            prompt=prompt,
            temperature=0.9,
            max_tokens=2048,
            top_p=1,
            frequency_penalty=0.0,
            presence_penalty=0.6,
            stop=[" Human:", "AI:"]
        )
        return JsonResponse({
            "type": "success",
            "text": response.choices[0].text,
        })
    except Exception as e:
        return JsonResponse({
            "type": "reject",
            "text": e,
        })
